<?php
/**
 * Created by PhpStorm.
 * User: shutao
 * Date: 2018/9/16
 * Time: 08:58
 */

namespace wechat\hook;

use tt\common\help\LogHelp;
use tt\common\help\ModelHelper;
use ttcommon\aop\annotation\HookAnnotation;
use wechat\models\WeUser;
use wechat\models\WeUserOpenid;
use wechat\services\WeChatMessage;
use wechat\services\WeConfigService;
use wechat\services\WeiXinService;
use yii\base\Event;
use yii\base\UserException;

/**
 * @title 微信公众号授权认证
 */
class AuthHook implements HookAnnotation
{
    public static $createUserWhenFirstSubscribe = false;
//    /** 因为我们在 login 中使用了与 ttext/backend/admin/hook/AuthHook 中同样的登录标记方式，所以这里就可以省略了
//     * @title 登录用户(多端支持) id
//     * @on rbac_uid
//     * @sort 1
//     * @param Event $event
//     */
//    public function userId(Event $event)
//    {
//        这里只是示例(通常不要写在这里)，你可以根据你的项目需要，实现自己的验证；
//  注意注解中的 sort 的值必须大于 0，否则会被系统默认验证给覆盖掉
//        if (isset($_GET['token'])) {
//            $event->data = 100; // 表示用户的 id
//            $event->handle = true; // 表示处理完成
//        }
//        RbacService::ON_RBAC_UID;
//
//    }

    /**
     * @title 关注时注册
     * @on wechat_event
     * @sort 100
     * @param Event $event
     * @param WeChatMessage $message
     * @throws \Exception
     */
    public static function wechatEvent(Event $event, $message)
    {
        WechatOn::EVENT;
        // // https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454
        $eventName = strtolower($message->event);
        if ('subscribe' == $eventName) {

            $transaction = \Yii::$app->db->beginTransaction();
            LogHelp::message('AuthHook:wechatEvent:subscribe----', 'wechat');
            // ToUserName	开发者微信号
            // FromUserName	发送方帐号（一个OpenID）---------- 此时还没有 unionid
            // 检查是否关注过(如果关注过，就已经注册过)
            if (!WeUserOpenid::find()->where(['user_openid' => $message->fromUserName])->exists()) {
                try {
                    // tt_user: 注册成为用户
                    $uid = self::$createUserWhenFirstSubscribe
                        ? WeiXinService::registerIfNotExits($message->fromUserName)
                        : 0;

                    // we_user: 注册成为微信用户
                    $weUser = new WeUser();
                    $weUser->uid = $uid;
                    $weUser->weixin_unionid = $message->fromUserName; // 授权后替换
                    $weUser->weixin_subscribed = 1;
                    $weUser->weixin_subscribed_at = time();
                    if ($weUser->insert() === false) {
                        LogHelp::message(ModelHelper::errorMessages($weUser), 'registerUser');
                        throw new UserException('保存微信用户关注信息时失败');
                    }
                    // we_user_openid: 登记应用来源
                    $open = new WeUserOpenid();
                    $open->we_id = $weUser->id;
                    $open->openid = $message->toUserName;
                    $open->user_openid = $message->fromUserName;
                    $open->type = WeConfigService::typeFromAppid($message->toUserName);
                    $open->insert();

                    $transaction->commit();
                } catch (\Exception $e) {
                    LogHelp::message('error:' . $e->getMessage(), 'registerUser');
                    $transaction->rollBack();
                    throw $e;
                }
            }

        }
    }
}